package main;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeSupport;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Klasa przechowujace dane gry po stronie klienta
 * @author Maciej Krawczyk
 * @see java.awt.event.ActionListener
 */
public class GuiData extends Thread implements ActionListener {

	/**Pole w ktorym przechowywany jest zaklad gracza, ktory zagral "Fold"*/
	static int foldStake;
	/**Strumien wyjsciowy*/
	private PrintWriter out;
	/**Strumien wejsciowy*/
	private BufferedReader in;
	/**Panel gry*/
	private GamePanel gp;
	/**Sprzezenie pomiedzy GUI a danymi*/
	private PropertyChangeSupport pcs;
	/**Dane przeciwnikow*/
	private OpponentData[] opponentsData;
	/**Etykieta kart i komunikatu*/
	private String cards, tip;
	/**Dane gracza (numer gracza, rola, liczba zetonow, laczna stawka na stole, stawka gracza)*/
	private int playerId, blind, players, chips, blindStake, pot, stake, round, pig;
	/**Flagi sterujace przeplywem rozgrywki*/
	private boolean dealt, endOfRound, created, dealtFirst, bet;
	/**Flaga sluzaca do podbijania rundy*/
	private boolean inc = true;
	/**Tabela przechowujaca role graczy (blind)*/
	private String[] blinds = { "DB", "SB", "BB",  "", "", "" };
	
	/**
	 * Konstruktor klasy z danymi gry po stronie klienta
	 * @param out strumien wyjsciowy
	 * @param in strumien wejscia
	 * @param gp glowny panel gry
	 */
	public GuiData(PrintWriter out, BufferedReader in, GamePanel gp) {
		
		this.out = out;
		this.in = in;
		this.gp = gp;		
		pcs = new PropertyChangeSupport(this);
	}
	
	/**
	 * Metoda przygotowuje GUI, pobiera i zapisuje odebrane dane inicjujace gre
	 * @param settings ustawienia gry
	 */
	public void install(String settings) {
		try {
			playerId = Integer.parseInt(settings.substring(0, 1));		
		} catch (NumberFormatException e) { return; }
		try {
			players = Integer.parseInt(settings.substring(1, 2));
			pig = players;
		} catch (NumberFormatException e) { return; }
		try {
			chips =  Integer.parseInt(settings.substring(2));
		} catch (NumberFormatException e) { return; }
	}
	
	/**
	 * Metoda wywolywana przy ponownym rozdaniu kart, ustawia karty, role graczy (blind), wysokosc big blind i small blind
	 * @param order wiadomosc przeslana przez serwer
	 */
	public void deal(String order) {

		try {
			blind = Integer.parseInt(order.substring(0, 1));
		} catch (NumberFormatException e) { return; }
		try {
			cards = order.substring(1, 9);
		} catch(StringIndexOutOfBoundsException e) { return; }
		try {
			blindStake =  Integer.parseInt(order.substring(9));
		} catch (NumberFormatException e) { return; }
		this.stake = 0;
		this.tip = "Welcome in Badugi game!";
		
		gp.createOpponents(playerId, players, blind);
		gp.createThemePanel();
		gp.createplayerPanel(this);
		gp.setId(this.playerId);
		gp.setAccesToPanel(0);
		
		opponentsData = new OpponentData[players];
		
		setOpponents();
		setOpChips();
		setOpBlinds();
		
		pcs.addPropertyChangeListener(gp.getPlayer());
		pcs.firePropertyChange("setBlind", "", blinds[blind]);
		if(blinds[blind].equals("SB")) {
			stake = blindStake;
			pcs.firePropertyChange("setStake", "", blindStake);
			chips -= blindStake;
			setChips(chips);
		}
		else if(blinds[blind].equals("BB")) {
			stake = (blindStake * 2);
			pcs.firePropertyChange("setStake", "", (blindStake * 2));
			chips -= (blindStake * 2);
			setChips(chips);
		}
		pcs.firePropertyChange("setChips", -1, chips);
		pcs.firePropertyChange("setTip", "", tip);
		pcs.firePropertyChange("setCards", "", cards);
	}
	
	/**
	 * Metoda wywolywana po kazdej rundzie gry, ustawia odpowiednie dane i modyfikuje GUI
	 * @param order wiadomosc po stronie serwera
	 */
	public void nextRound(String order) {
		try {
			blind = Integer.parseInt(order.substring(0, 1));
		} catch (NumberFormatException e) { return; }
		try {
			cards = order.substring(1, 9);
		} catch(StringIndexOutOfBoundsException e) { return; }
		try {
			blindStake =  Integer.parseInt(order.substring(9));
		} catch (NumberFormatException e) { return; }
		setStake(0);
		clearOpStakes();
		pcs.firePropertyChange("setBlind", "", blinds[blind]);
		if(blinds[blind].equals("SB")) {
			if(chips >= blindStake) {
				stake = this.blindStake;
				pcs.firePropertyChange("setStake", "", blindStake);
				chips -= this.blindStake;
				setChips(chips);
			} else {
				stake = chips;
				pcs.firePropertyChange("setStake", "", chips);
				chips = 0;
				setChips(0);
			}
		}
		else if(blinds[blind].equals("BB")) {
			if(chips >= blindStake) {
				stake = (this.blindStake * 2);
				pcs.firePropertyChange("setStake", "", (blindStake * 2));
				chips -= (blindStake * 2);
				setChips(chips);
			} else {
				stake = chips;
				pcs.firePropertyChange("setStake", "", chips);
				chips = 0;
				setChips(0);
			}
		}
		setCards(cards);
		setOpBlindsN();
		computePot();
		clearOpStates();
		setTip("Let's play new game!");
		gp.pack();
	}
	
	/**
	 * Metoda ustawia role gracza (blind)
	 * @param blind rola gracza
	 */
	public void setBlind(int blind) {
		int old = this.blind;
		this.blind = blind;
		pcs.firePropertyChange("setBlind", old, blinds[blind]);
	}
	
	/**Metoda ustawia role przeciwnikow (blind)*/
	public void setOpBlinds() {
		int k = 0;
		for(int i = 0; i < players; i++) 
			if(i == playerId) {
				continue;
			}
			else if(opponentsData[i] == null) {
				k++;
				continue;
			}
			else {
				String b = blinds[(blind + i - k - playerId + players) % players];
				opponentsData[i].setBlind(b);
				
				if(b.equals("SB")) {
					opponentsData[i].setStake(this.blindStake);
					opponentsData[i].setChips(chips - blindStake);
				}
				else if (b.equals("BB")) {
					opponentsData[i].setStake((this.blindStake * 2));
					opponentsData[i].setChips(chips - (blindStake * 2));
				}
			}
		bet = true;
	}
	
	/**
	 * Metoda ustawia komunikat/porade dla gracza zaleznie od etapu gry
	 * @param tip komunikat/porada w GUI gracza
	 */
	public void setTip(String tip) {
		String old = this.tip;
		this.tip = tip;
		pcs.firePropertyChange("setTip", old, this.tip);
	}
	
	/**Metoda czysci statusy przeciwnikow*/
	public void clearOpStates() {
		for(int i = 0; i < players; i++)
			if(i == playerId || (opponentsData[i] == null))
				continue;
			else {
				if(opponentsData[i].getChips() != 0)
					opponentsData[i].setState("Waiting");
				else
					opponentsData[i].setState("All-In");
			}
	}
	
	/**Metoda ustawia role przeciwnikow (blind)*/
	public void setOpBlindsN() {
		
		int k = (blind + 1) % pig;
		int j = (playerId + 1) % players;
		for(int i = 0; i < players - 1; i++) {
			if(opponentsData[j] != null) {
				if(!(blind == 1 && pig == 2))
					opponentsData[j].setBlind(blinds[k]);
				else {
					k = 2;
					opponentsData[j].setBlind(blinds[k]);
				}
				if (k == 1) {
					if(opponentsData[j].getChips() >= blindStake) {
						opponentsData[j].setStake(blindStake);
						opponentsData[j].setChips(opponentsData[j].getChips() - (blindStake));
					} else {
						opponentsData[j].setStake(opponentsData[j].getChips());
						opponentsData[j].setChips(0);
					}
				} else if ((k == 2)) {	//  || (k == 0 && pig == 2)
					if(opponentsData[j].getChips() >= blindStake) {
						opponentsData[j].setStake(blindStake * 2);
						opponentsData[j].setChips(opponentsData[j].getChips() - (blindStake * 2));
					} else {
						opponentsData[j].setStake(opponentsData[j].getChips());
						opponentsData[j].setChips(0);
					}
				}
				k = (k + 1) % pig;
			}
			j = (j + 1) % players;
		}
		bet = true;	
	}
	
	/**
	 * Metoda ustawia karty gracza
	 * @param cards karty gracza
	 */
	public void setCards(String cards) {
		this.cards = cards;
		pcs.firePropertyChange("setCards", "", this.cards);
	}
	
	/**
	 * Metoda ustawia stawke gracza
	 * @param stake wysokosc stawki
	 */
	public void setStake(int stake) {
		int old = this.stake;
		this.stake = stake;
		pcs.firePropertyChange("setStake", old, this.stake);
	}
	
	/**Metoda resetuje stawki graczy*/
	public void clearOpStakes() {
		for(int i = 0; i < players; i++)
			if(i == playerId || (opponentsData[i] == null))
				continue;
			else {
				opponentsData[i].setStake(0);
			}
	}
	
	/**
	 * Metoda ustawia zetony gracza
	 * @param chips liczba zetonow
	 */
	public void setChips(int chips) {
		this.chips = chips;
		pcs.firePropertyChange("setChips", -1, this.chips);
	} 
	
	/**Metoda ustawia zetony przeciwnikom*/
	public void setOpChips() {
		for(int i = 0; i < players; i++)
			if(i == playerId || (opponentsData[i] == null))
				continue;
			else {
				opponentsData[i].setChips(this.chips);
			}
	}
	
	/**Metoda aktualizuje laczna ilosc zetonow postawionych przez graczy*/
	public void computePot() {
		int pot = this.stake;
		for(int i = 0; i < players; i++)
			if(i == playerId || (opponentsData[i] == null))
				continue;
			else
				pot += (int) opponentsData[i].getStake();
		pot += foldStake;
		setPot(pot);
	}
	
	/**
	 * Metoda ustawia laczna liczbe zetonow na stole
	 * @param pot laczna liczba zetonow na stole
	 */
	public void setPot(int pot) {
		this.pot = pot;
		pcs.firePropertyChange("setPot", -1, this.pot);
	}
	
	/**Metoda pobiera panele przeciwnikow w celu informowania gracza o ich ruchach w trakcie rozgrywki*/
	public void setOpponents() {
		for(int i = 0; i < players; i++)
			if(i == playerId)
				continue;
			else
				opponentsData[i] = new OpponentData(gp.getOpponent(i));		
	}
	
	/**
	 * Metoda zwraca maksymalna stawke postawiona wsrod graczy
	 * @return wysokosc stawki
	 */
	public int getMaxStake() {
		int maxStake = stake;
		for(int i = 0; i < players; i++)
			if(i == playerId || (opponentsData[i] == null))
				continue;
			else if(opponentsData[i].getStake() > maxStake)
				maxStake = opponentsData[i].getStake();
		
		if(maxStake < blindStake * 2)
			return blindStake * 2;
		else
			return maxStake;
	}
	
	/**
	 * Metoda ustawia status danego przeciwnika na "Check"
	 * @param id numer przeciwnika
	 */
	public void opCheck(int id) {
		opponentsData[id].check();
	}
	
	/**
	 * Metoda ustawia status przeciwnika na "Call"
	 * @param id numer przeciwnika
	 */
	public void opCall(int id) {
		if((getMaxStake() - opponentsData[id].getStake()) < opponentsData[id].getChips())
			opponentsData[id].up(getMaxStake(), "Call");
	}
	
	/**
	 * Metoda ustawia status przeciwnika na "Bet"
	 * @param id numer przeciwnika
	 * @param value wysokosc stawki
	 */
	public void opBet(int id, String value) {
		int stake;
		try {
			stake = Integer.parseInt(value);
		} catch (NumberFormatException e) { return; }
		if(stake < opponentsData[id].getChips())
			opponentsData[id].up(getMaxStake() + stake, "Bet " + stake);
		bet = true;
	}
	
	/**
	 * Metoda ustawia status przeciwnika na "Raise"
	 * @param id numer przeciwnika
	 * @param value wysokosc stawki
	 */
	public void opRaise(int id, String value) {
		int stake;
		try {
			stake = Integer.parseInt(value);
		} catch (NumberFormatException e) { return; }
		if(stake < opponentsData[id].getChips())
			opponentsData[id].up(getMaxStake() + stake, "Raise " + stake);
	}
	
	/**
	 * Metoda ustawia status przeciwnika na "Fold"
	 * @param id numer przeciwnika
	 */
	public void opFold(int id) {
		opponentsData[id].fold();
	}
	
	/**
	 * Metoda ustawia status przeciwnika na "All-In"
	 * @param id numer przeciwnika
	 */
	public void opAllIn(int id) {
		opponentsData[id].allIn();
	}
	
	/**
	 * Metoda podbija stawke gracza o okreslona wartosc
	 * @param stake wysokosc stawki
	 */
	public void up(int stake) {
		setChips(chips - (stake - this.stake));
		setStake(stake);
	}
	
	/**Metoda symulujaca zagranie "Call" przez gracza*/
	public void call() {
            up(getMaxStake());
	}
	
	/**
	 * Metoda symulujaca zagranie "Raise" przez gracza
	 * @param stake wysokosc stawki
	 */
	public void raise(int stake) {
//		if((stake + getMaxStake()) <= chips)
			up(stake + getMaxStake());
//		else {
//			setTip("Come on! You don't have enough chips.");
			gp.clearFields();
//		}
	}
	
	/**
	 * Metoda symulujaca zagranie "Bet" przez gracza
	 * @param stake wysokosc stawki
	 */
	public void bet(int stake) {
//		if((stake + getMaxStake()) <= chips)
			up(getMaxStake() + stake);
			bet = true;
//		else {
//			setTip("Play fairly, you little pickle...");
			gp.clearFields();
//		}
	}
	
	/**Metoda symulujaca zagranie "Fold" przez gracza*/
	public void fold() {
		foldStake += stake;
		setStake(0);
	}
	
	/**Metoda symulujaca zagranie "All-In" przez gracza*/
	public void allIn() {
		setStake(stake + chips);
		setChips(0);
	}
	
	/**
	 * Metoda pobiera od gracza karty, ktore zyczy sobie wymienic
	 * @return karty do wymiany
	 */
	public String exchange() {
		String cte = "";
		if(gp.isCheckbox1())
			cte += cards.substring(0, 2);
		if(gp.isCheckbox2())
			cte += cards.substring(2, 4);
		if(gp.isCheckbox3())
			cte += cards.substring(4, 6);
		if(gp.isCheckbox4())
			cte += 	cards.substring(6, 8);
		if(cte.equals(""))
			cte = "";
		return cte;
	}
	
	/**
	 * Metoda ruchu przeciwnika
	 * @param order ruch przeciwnika
	 */
	public void opMove(String order) {
		int id;
		try {
			String a = order.substring(0,1);
			id = Integer.parseInt(a);
		} catch (NumberFormatException e) { return; }
		
		String move = order.substring(1,2);
		String stake;
		switch (move) {
		case "C":
			opCheck(id);
			break;
		case "K":
			opCall(id);
			computePot();
			break;
		case "B":
			stake = order.substring(2);
			opBet(id, stake);
			computePot();
			break;
		case "R":
			stake = order.substring(2);
			opRaise(id, stake);
			computePot();
			break;
		case "F":
			opFold(id);
			computePot();
			break;
		case "A":
			opAllIn(id);
			computePot();
			break;
			
		default:
			System.out.println(move);
			System.out.println("Nieznany ruch przeciwnika");
			break;
		}
	}
	
	/**
	 * Metoda wymiany kart przez przeciwnika
	 * @param order ktory przeciwnik i ile kart zyczy sobie wymienic
	 */
	public void opExchange(String order) {
		int opId, howMany;
		try {
			String a = order.substring(0,1);
			String b = order.substring(1,2);
			opId = Integer.parseInt(a);
			howMany = Integer.parseInt(b);
		} catch (NumberFormatException e) { return; }
		gp.opExchange(opId, howMany);
	}
	
	/**Metoda ustawia dostep do komponentow gracza na podstawie etapu gry*/
	public void setAcces() {
		if(stake == getMaxStake()) {
			gp.setAToCheck(true);
			gp.setAToCall(false);
		} else {
			gp.setAToCheck(false);
			gp.setAToCall(true);
		}
// && (!dealt || !dealtFirst) w ifie (getMaxStake() == blindStake * 2)
		if(!bet){// && (dealt || dealtFirst)) {
			gp.setAToBet(true);
			gp.setAToBetField(true);
			gp.setAToRaise(false);
			gp.setAToRaiseField(false);
		}
		else {
			gp.setAToBet(false);
			gp.setAToBetField(false);
			gp.setAToRaise(true);
			gp.setAToRaiseField(true);
		}
		
		if(getMaxStake() >= chips + stake) {
			gp.setAToCall(false);
			gp.setAToCheck(false);
			gp.setAToBet(false);
			gp.setAToBetField(false);
			gp.setAToRaise(false);
			gp.setAToRaiseField(false);
			gp.setAToAllIn(true);
		}
		gp.setAToFold(true);
	}
	
	/**Metoda usuwa graczy, ktorzy przegrali na koniec kazdej partii*/
	public void removePlayers() {
		if(chips == 0) {
			gp.showLoserDialog();
			System.exit(0);
		}
		else {
			for(int i = 0; i < players; i++) {
				if(i == playerId || (opponentsData[i] == null))
					continue;
				else if(opponentsData[i].getChips() == 0) {
					//System.out.println("tu");
					remove(i);
				}
			}
		}
	}
	
	/**
	 * Metoda usuwany konkretnego gracza z gry
	 * @param i numer gracza przeznaczonego do usuniecia
	 */
	public void remove(int i) {
		System.out.println("usuwamy "+ (pig-1) + " " + i+" "+ opponentsData[i].getChips());
		
		pig -= 1;
		
		if (pig == 1) {
			gp.showWinnerDialog();
			gp.pack();
			System.exit(0);
		}
		
		gp.removeOp(i);
		//foldStake = opponentsData[i].getStake();
		opponentsData[i] = null;
		//System.out.println("pig = " + pig);
	}
	
	/**
	 * Metoda odslaniajaca karty przeciwnikow, ktorzy nie zagrali "Fold" pod koniec kazdej partii
	 * @param winner wygrany w danej partii
	 */
	public void showCards(int winner) {
		gp.showCards(players);
		String cards = "", converted = "";
		for(int i = 0; i < players; i++) {
			try {
				cards = in.readLine();
				System.out.println(cards);
			} catch (IOException e) {
				System.out.println("Nie przechwycono kart (po rozgrywce)");
			}
			if(cards.equals("X"))
				gp.addLabel("Player " + i + " -> Folded");
			else {
				converted = convert(cards);
				System.out.println(cards);
				if(i == winner)
					gp.addLabel("Player " + i + " -> " + converted + "Winner");
				else
					gp.addLabel("Player " + i + " -> " + converted);
			}
		}
		gp.addButton();
	}
	
	/**
	 * Metoda zamieniajaca karty gracza z postaci surowej na przystepniejsza postac
	 * @param cards surowa wersja kart gracza
	 * @return zmieniona wersja kart gracza zgodnie z kolorami kart, dzieki tablicy ASCII
	 */
	public String convert(String cards) {
		String product = "";
		for(int i = 0; i < cards.length(); i += 2) {
			if(cards.substring(i, i + 1).equals("0"))
				product += "10";
			else
				product += cards.substring(i, i + 1);
			if(cards.substring(i + 1, i + 2).equals("c"))
				product += "\u2663";
			else if(cards.substring(i + 1, i + 2).equals("s"))
				product += "\u2660";
			else if(cards.substring(i + 1, i + 2).equals("d"))
				product += "\u2666";
			else
				product += "\u2665";
			product += "  ";
		}
		return product;
	}
	
	/**Metoda nasluchuje w celu odebrania wiadomosci z serwera*/
	@Override
	public void run() {
		while(true)
			receive();
	}
	
	/**
	 * Metoda wysyla wiadomosci na serwer
	 * @param msg wiadomosc
	 */
	public void send(String msg) {
		out.println(msg);
	}
	
	/**Metoda odbiera wiadomosci z serwera i steruje przeplywem rozgrywki*/
	public void receive() {
		try {
			String order, settings;
			if(!created) {
				settings = in.readLine();
				install(settings);
				created= true;
				System.out.println(settings);
			}			
			else if(!dealtFirst) {
				order = in.readLine();
				deal(order);
				computePot();
				dealtFirst = true;
				dealt = true;
				System.out.println(order);
			}
			else if(!dealt) {
				order = in.readLine();
				System.out.println(order);
				nextRound(order);
				dealt = true;
				System.out.println(order);
			}
			else if(!endOfRound) {
				gp.pack();
				order = in.readLine();
				System.out.println(order);
				try {
					Integer.parseInt(order.substring(0,1));
					if(inc) {
						round++;
						inc = false;
					}
				} catch (Exception e) { inc = true; }
				gp.setRoundLabel("Round " + round);
				String myTurn = Integer.toString(playerId);
				String myExchangeTurn = "E" + myTurn;
				if(myTurn.equals(order)) {		
					setAcces();
					if(chips < 200)
						setTip("To fold, or not to fold? That is the question.");
					else
						setTip("It's your turn!");
				}
				else if(myExchangeTurn.equals(order)) {
					setTip("Exchange your cards and crush suckers...");
					gp.setAccesToPanel(1);
					gp.pack();
					String newCards = in.readLine();
					System.out.println(newCards);
	
					bet = false;
					gp.setAccesToPanel(0);
					setCards(newCards);
				}
				else {
					if(chips != 0)
						setTip("Skill + Chips = More Chips");
					else
						setTip("Count to ten and take a deep breath.");
					int opId;
					try {
						opId = Integer.parseInt(order.substring(order.length() - 1));
					} catch (NumberFormatException ex) {
						System.out.println("Nieprawidlowy komounikat o ruchu przeciwnika");
						return;
					}
					gp.setAccesToPanel(0);
					if(order.substring(0,1).equals("E")) {
						gp.highlightOp(opId);
						opponentsData[opId].setState("Exchanging");
						gp.pack();
						bet = false;
						order = in.readLine();
						if(order.substring(0,1).equals("S")) {
							int refugee;
							try {
								refugee = Integer.parseInt(order.substring(1,2));
								remove(refugee);
								order = in.readLine();
							} catch (Exception e) {
								System.out.println(order);
								System.out.println("Nieudane usuniecie gracza");
							}
						}
						System.out.println(order);
						opExchange(order);
						gp.pack();
					}
					else if(order.substring(0,1).equals("W")) {
						setTip("#BADUGI  #Phil Ivey  #high roller");
						int winner, prize;
						try {
							winner = Integer.parseInt(order.substring(1,2));
							prize = Integer.parseInt(order.substring(2));
						} catch (Exception e) {
							System.out.println("Nieprawidlowy komounikat - wygrana gry");
							return;
						}
						if(winner == playerId) {
							setChips(prize + chips);
						} else {
							int oldChips = opponentsData[winner].getChips();
							int t = prize + oldChips;
							opponentsData[winner].setChips(t);
						}
						foldStake = 0;
						round = 0;
						dealt = false;
						setPot(0);
						gp.pack();
						showCards(winner);
						setBlind(5);
						for (int i = 0; i < players; i++) {
							if(i == playerId || (opponentsData[i] == null))
								continue;
							else
								gp.resetFold(i);
						}
						removePlayers();
					}
					else if(order.substring(0,1).equals("D")) {
						System.out.println(order);
						foldStake = 0;
						round = 0;
						dealt = false;
						setPot(0);
						gp.pack();
						showCards(-1);
						setBlind(5);
						for (int i=0; i < players; i++) {
							if(i == playerId || (opponentsData[i] == null))
								continue;
							else
								gp.resetFold(i);
						}
						removePlayers();
					}
					else {
						gp.highlightOp(opId);
						opponentsData[opId].setState("Bidding");
						gp.pack();
						order = in.readLine();
						System.out.println(order);
						if(order.substring(0,1).equals("S")) {
							int refugee;
							try {
								refugee = Integer.parseInt(order.substring(1,2));
								remove(refugee);
							} catch (Exception e) {
								System.out.println(order);
								System.out.println("Nieudane usuniecie gracza");
							}
						} else
							opMove(order);
							gp.pack();
					}
					if (opId != playerId) {
						gp.putOffOp(opId);
					}
				}
			}
			else {
				order = in.readLine();
				System.out.println(order);
			}
		} catch (IOException ex) { System.out.println(endOfRound); System.out.println("Nie przechwycono danych"); System.exit(-1);}
		gp.pack();
	}

	/**Metoda reaguje na aktywnosc gracza (obsluga wciskanych przyciskow)*/
	@Override
	public void actionPerformed(ActionEvent e) {
		String msg = e.getActionCommand();
		if(msg.equals("Call")) {
			call();
			send("K");
		}
		else if(msg.equals("Raise")) {
			int stake;
			try {
				stake = Integer.parseInt(gp.getRaise());
				System.out.println(stake);
				if (stake <= 0) {
					setTip("Please click \"Call\" or raise stake");
					gp.clearFields();
					return;			
				}
				else if(getMaxStake() + stake - this.stake > chips) {
					setTip("Play fairly, you little pickle...");
					gp.clearFields();
					return;	
				}
			} catch (NumberFormatException ex) {
				setTip("Please key in a number.");
				return;
			}
			raise(stake);
			send("R" + stake);
		}
		else if(msg.equals("Bet")) {
			int stake;
			try {
				stake = Integer.parseInt(gp.getBet());
				if (stake <= 0) {
					setTip("Please click \"Call\" or raise stake");
					gp.clearFields();
					return;
				}
				else if(getMaxStake() + stake - this.stake > chips) {
					setTip("Play fairly, you little pickle...");
					gp.clearFields();
					return;
				}
			} catch (NumberFormatException ex) { 
				setTip("Please key in a number.");
				return;
			}
			bet(stake);
			send("B" + stake);
		}
		else if(msg.equals("Fold")) {
			fold();
			send("F");
		}
		else if(msg.equals("All-In")) {
			allIn();
			send("A");
		}
		else if (msg.equals("Exchange")) {
			send(exchange());
			gp.clearCheckboxes();
		}
		else if(msg.equals("Skip"))
			send("");
		else
			send(msg.substring(0, 1));	
		
		computePot();
		gp.pack();
	}

}
